﻿#ifndef __AVOID_BW_CONTROL_X_EVENTTRANDLATE_HEAD_FILE_INCLUDED__
#define __AVOID_BW_CONTROL_X_EVENTTRANDLATE_HEAD_FILE_INCLUDED__
#include "xctlDefine.h"
#include <vector>
#include <algorithm>
#include <functional>
#include <mutex>

namespace swui
{
	class ctlRoot;
	namespace _ctlInterior
	{
		class eventTranslator
		{
			eventTranslator(const eventTranslator&);
		public:
			eventTranslator() {};
			typedef std::vector<ctlRoot*> containType;
			const containType& getChildEnumerator() { return childControls; }
		public:
			//下面三个函数针对子控件
			void setZOrderTop(ctlRoot*);
			bool isZOrderTop(ctlRoot*);
			unsigned zordNumber() { return zord_top.size(); }
			void relateParent(ctlRoot* parent);
			void setRelation(ctlRoot* relation) { this->relation = relation; }
			void setCapture();
			void releaseCapture();
			ctlPoint pointTrans(ctlPoint, ctlRoot* from);
			unsigned setTimer(unsigned elapse, std::function<bool()>);
			void killTimer(unsigned id);
			void moveTo(unsigned pos);
			void setParent(ctlRoot*);
			void clear() { childControls.clear(); zord_top.clear(); }
			void lock() { child_mutex.lock(); }
			void unlock() { child_mutex.unlock(); }
			eventTranslator& getControlEventTrans(ctlRoot* root);
		public:
			ctlRect getParentRect();
		public:
			void draw(drawInfo*);
			bool mouse(ctlMouseEvent*);
			bool vicMouse(ctlMouseEvent&, ctlRoot* ctl, bool check = true);
		private:
			containType childControls;
			ctlRoot* relation;
			ctlRoot* topest;
			containType zord_top;
			majorInfo* mInfo;
			std::recursive_mutex child_mutex;
		public:
			void push(ctlRoot* ptr) 
			{
				std::lock_guard<decltype(child_mutex)> gurad(child_mutex);
				if(zord_top.size() == 0)
					childControls.push_back(ptr);
				else childControls.insert(childControls.end() - zord_top.size(), ptr);
			}
			void pop(ctlRoot* ptr) 
			{
				std::lock_guard<decltype(child_mutex)> gurad(child_mutex);
				containType::iterator result = 
					std::find(childControls.begin(), childControls.end(), ptr);
				if(result != childControls.end()) childControls.erase(result);
				containType::iterator result2 = 
					std::find(zord_top.begin(), zord_top.end(), ptr);
				if(result2 != zord_top.end()) zord_top.erase(result2);
			}
			bool empty() { return childControls.empty(); }
			void setFocus();
			void killFocus();
		public:
			majorInfo* getMajorInfo() { return mInfo; }
			ctlRoot* getTopest() { return topest; }
			ctlRoot* getFront() { return childControls.front(); }
			ctlRoot* getBack() { return childControls.back(); }
			void setMajorInfoAndRoot(majorInfo* minfo, ctlRoot *root)
			{
				mInfo = minfo;
				topest = root;
			}
		public:
			void setCursor(std::wstring::const_pointer name);
			void releaseCursor();
		};
	}
}	//namespace swui

#endif